package com.aryankh.wordbookfx.service;


import com.aryankh.wordbookfx.constant.PathConstants;
import com.aryankh.wordbookfx.constant.SqliteConstants;
import com.aryankh.wordbookfx.dao.WordDao;
import com.aryankh.wordbookfx.entity.ReloadWordEntity;
import com.aryankh.wordbookfx.entity.WordEntity;
import com.aryankh.wordbookfx.util.CharacterUtil;
import com.aryankh.wordbookfx.util.LocalFileUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author AryanKH
 * @Date 2023/4/20 15:27
 */
@Service
public class WordService {
    @Resource
    WordDao wordDao;

    public Long getCount() {
        return wordDao.selectCount(null);
    }

    public ReloadWordEntity getWordByEnglish(String sourceWord) {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(WordEntity::getWord, sourceWord);
        WordEntity wordEntity = wordDao.selectOne(queryWrapper);
        return new ReloadWordEntity(wordEntity.getWord(), wordEntity.getExplanation());
    }

    public int addWord(String word, String explanation) {
        if (!CharacterUtil.isChinese(word) && CharacterUtil.isChinese(explanation)) {
            WordEntity wordEntity = new WordEntity();
            LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WordEntity::getWord, word);
            if (word.length() > 0 && explanation.length() > 0) {
                if ((wordDao.selectOne(queryWrapper)) == null) {
                    wordEntity.setId(null);
                    wordEntity.setWord(word);
                    wordEntity.setExplanation(explanation);
                    wordEntity.setPhonetic(null);
                    wordEntity.setSourceLanguage("auto");
                    wordEntity.setTargetLanguage("zh-CN");
                    wordEntity.setTags(null);
                    wordEntity.setCreatedAt(String.valueOf(System.currentTimeMillis()));
                    return wordDao.insert(wordEntity);
                } else {

                    return -1;
                }
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    public void reloadDBFile() {
        if (!new File(PathConstants.C_PATH + PathConstants.DB_NAME).exists()) {
            try {
                InputStream inputStream = getClass().getResourceAsStream(PathConstants.CLASS_PATH_RESOURCE_PATH);
                FileOutputStream fileOutputStream = new FileOutputStream(PathConstants.C_DB_NAME);
                byte[] data = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = inputStream.read(data)) != -1) {
                    fileOutputStream.write(data, 0, bytesRead);
                }
                System.out.println("File copied successfully!");
                inputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println("File reloaded successfully!");
        }

    }


    public void reloadTheme(String themeName) {
        if (!new File(PathConstants.C_PATH + PathConstants.THEME_NAME).exists()) {
            try {
                FileOutputStream fileOutputStream = new FileOutputStream(PathConstants.C_THEME_NAME);
                fileOutputStream.write(themeName.getBytes());
                System.out.println("File copied successfully!");
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println("File reloaded successfully!");
        }

    }

    public List<ReloadWordEntity> getAllWords() {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        List<WordEntity> wordEntities = wordDao.selectList(queryWrapper);
        ArrayList<ReloadWordEntity> reloadWordEntities = new ArrayList<>(128);
        wordEntities.forEach(wordEntity -> {
            ReloadWordEntity reloadWordEntity = new ReloadWordEntity();
            reloadWordEntity.setWord(wordEntity.getWord());
            reloadWordEntity.setExplanation(wordEntity.getExplanation());
            reloadWordEntities.add(reloadWordEntity);
        });
        return reloadWordEntities;
    }

    public ReloadWordEntity getWordByChinese(String explanation) {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(WordEntity::getExplanation, explanation);
        WordEntity wordEntity = wordDao.selectOne(queryWrapper);
        return new ReloadWordEntity(wordEntity.getWord(), wordEntity.getExplanation());
    }

    public List<ReloadWordEntity> getWordByChineseWithTableName(String explanation, String tableName) {
        List<WordEntity> wordEntities = wordDao.getWordByChineseWithTableName(explanation, tableName);
        List<ReloadWordEntity> reloadWordEntities = new ArrayList<>();
        for (WordEntity wordEntity : wordEntities) {
            reloadWordEntities.add(new ReloadWordEntity(wordEntity.getWord(), wordEntity.getExplanation()));
        }
        return reloadWordEntities;
    }

    public void updateWord(String word, String explanation) {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WordEntity::getExplanation, explanation);
        Integer id = wordDao.selectOne(queryWrapper).getId();
        LambdaUpdateWrapper<WordEntity> wordEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        wordEntityLambdaUpdateWrapper.eq(WordEntity::getExplanation, explanation).eq(WordEntity::getId, id);
        WordEntity wordEntity = new WordEntity();
        wordEntity.setWord(word);
        wordDao.update(wordEntity, wordEntityLambdaUpdateWrapper);
    }

    public void updateExplanation(String explanation, String word) {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WordEntity::getWord, word);
        Integer id = wordDao.selectOne(queryWrapper).getId();
        LambdaUpdateWrapper<WordEntity> wordEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        wordEntityLambdaUpdateWrapper.eq(WordEntity::getWord, word).eq(WordEntity::getId, id);
        WordEntity wordEntity = new WordEntity();
        wordEntity.setExplanation(explanation);
        wordDao.update(wordEntity, wordEntityLambdaUpdateWrapper);
    }

    public void deleteWord(String word, String explanation) {
        LambdaQueryWrapper<WordEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WordEntity::getExplanation, explanation).eq(WordEntity::getWord, word);
        Integer id = wordDao.selectOne(queryWrapper).getId();

        LambdaUpdateWrapper<WordEntity> wordEntityLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        wordEntityLambdaUpdateWrapper.eq(WordEntity::getExplanation, explanation)
                .eq(WordEntity::getWord, word)
                .eq(WordEntity::getId, id);
        wordDao.delete(wordEntityLambdaUpdateWrapper);
    }


    public List<String> checkAllTableAndCount() {
        List<String> tables = wordDao.allTable();
        // sqlite_sequence
        for (int i = 0; i < tables.size(); i++) {
            if (SqliteConstants.SQLITE_SEQUENCE.equals(tables.get(i))) {
                tables.remove(i);
            }
        }
        return tables;
    }

    public void createTable(String tableName) {
        wordDao.createTable(tableName);
    }

    public int addWordWithTableName(String word, String explanation, String tableName) {
        if (!CharacterUtil.isChinese(word) && CharacterUtil.isChinese(explanation)) {
            WordEntity wordEntity = new WordEntity();
            if (word.length() > 0 && explanation.length() > 0) {
                if (word.contains("'")) {
                    String[] split = word.split("'");
                    word = split[0] + "''" + split[1];
                }
                // decline verification : look over isDuplication
                wordEntity.setId(null);
                wordEntity.setWord(word);
                wordEntity.setExplanation(explanation);
                wordEntity.setPhonetic(null);
                wordEntity.setSourceLanguage("auto");
                wordEntity.setTargetLanguage("zh-CN");
                wordEntity.setTags(null);
                wordEntity.setCreatedAt(String.valueOf(System.currentTimeMillis()));
                return wordDao.insertWithTableName(wordEntity, tableName);
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    public ReloadWordEntity getWordByEnglishWithTableName(String word, String tableName) {
        if (word.contains("'")) {
            String[] split = word.split("'");
            word = split[0] + "''" + split[1];
        }
        WordEntity wordEntity = wordDao.getWordByEnglishWithTableName(word, tableName);
        return new ReloadWordEntity(wordEntity.getWord(), wordEntity.getExplanation());
    }

    public Long getCountWithTableName(String tableName) {
        return wordDao.getCountWithTableName(tableName);
    }

    public List<ReloadWordEntity> getAllWordsWithTableName(String tableName) {
        List<WordEntity> wordEntities = wordDao.selectAllWithTableName(tableName);
        ArrayList<ReloadWordEntity> reloadWordEntities = new ArrayList<>(128);
        wordEntities.forEach(wordEntity -> {
            ReloadWordEntity reloadWordEntity = new ReloadWordEntity();
            reloadWordEntity.setWord(wordEntity.getWord());
            reloadWordEntity.setExplanation(wordEntity.getExplanation());
            reloadWordEntities.add(reloadWordEntity);
        });
        return reloadWordEntities;
    }

    public void updateExplanationWithTableName(String newExplanation,
                                               String word,
                                               String tableName) {

        int id = wordDao.getIdByWordWithTableName(word, tableName);

        wordDao.updateExplanationWithTableName(id, newExplanation, tableName);
    }

    public void deleteWordWithTableName(String word, String explanation, String tableName) {
        if (word.contains("'")) {
            String[] split = word.split("'");
            word = split[0] + "''" + split[1];
        }
        int id = wordDao.getIdByWordAndExplanationWithTableName(tableName, explanation, word);
        wordDao.deleteByIdWithTableName(id, LocalFileUtils.getTableName());
    }

    public void updateWordWithTableName(String word, String explanation, String newValue, String tableName) {
        if (word.contains("'")) {
            String[] split = word.split("'");
            word = split[0] + "''" + split[1];
        }
        if (newValue.contains("'")) {
            String[] split = newValue.split("'");
            newValue = split[0] + "''" + split[1];
        }
        int id = wordDao.getIdByWordAndExplanationWithTableName(tableName, explanation, word);
        wordDao.updateWordWithTableName(id, newValue, tableName);
    }
}
